package main

// Author：孙子烧烤
// Website：www.sunzishaokao.com
// Tips：本项目免费开源，禁止商业用途，仅供学习交流使用。
import (
	"encoding/json"
	"fmt"
	"gopkg.in/yaml.v2"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"strconv"
)

// Message struct to map the incoming webhook request body
type Message struct {
	Message string `json:"message"`
}

// Config struct to map the configuration settings
type Config struct {
	Port      int    `yaml:"port"`
	SecretKey string `yaml:"secret_key"`
}

// sendPrivateQQMessage sends a private message to a specific QQ user
func sendPrivateQQMessage(qqid string, message string) {
	url := fmt.Sprintf("http://127.0.0.1:5700/send_private_msg?user_id=%s&message=%s", qqid, message)
	cmd := exec.Command("curl", "-X", "POST", url)
	err := cmd.Run()
	if err != nil {
		log.Printf("Failed to send private message: %v", err)
	}
}

// sendGroupQQMessage sends a message to a specific QQ group
func sendGroupQQMessage(groupID string, message string) {
	url := fmt.Sprintf("http://127.0.0.1:5700/send_group_msg?group_id=%s&message=%s", groupID, message)
	cmd := exec.Command("curl", "-X", "POST", url)
	err := cmd.Run()
	if err != nil {
		log.Printf("Failed to send group message: %v", err)
	}
}

func webhookHandler(w http.ResponseWriter, r *http.Request) {
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, "Error reading request body", http.StatusInternalServerError)
		return
	}

	var msg Message
	err = json.Unmarshal(body, &msg)
	if err != nil {
		http.Error(w, "Error parsing request body", http.StatusInternalServerError)
		return
	}

	qqid := r.URL.Query().Get("userid")
	groupID := r.URL.Query().Get("groupid")
	messageType := r.URL.Query().Get("message_type")

	if messageType == "user" && qqid != "" {
		sendPrivateQQMessage(qqid, msg.Message)
		fmt.Fprintf(w, "已经发送至: %s", qqid)
	} else if messageType == "group" && groupID != "" {
		sendGroupQQMessage(groupID, msg.Message)
		fmt.Fprintf(w, "已经发送至: %s", groupID)
	} else {
		http.Error(w, "Invalid 'message_type' parameter or missing 'userid'/'groupid'", http.StatusBadRequest)
		return
	}

	w.WriteHeader(http.StatusOK)
}

func main() {
	fmt.Printf("作者：孙子烧烤\n")
	fmt.Printf("网站：www.sunzishaokao.com\n")
	fmt.Printf("本项目免费开源，禁止商业用途，仅供学习交流使用。\n")
	configPath := "config.yaml"
	defaultPort := 8080 // 默认端口号

	// 检查config.yaml是否存在
	if _, err := os.Stat(configPath); os.IsNotExist(err) {
		// 创建一个新的配置文件，不包含密钥值
		newConfig := Config{
			Port:      defaultPort,
			SecretKey: "", // 不包含密钥值
		}

		// 将配置结构体序列化为YAML
		configData, err := yaml.Marshal(newConfig)
		if err != nil {
			log.Fatalf("Failed to marshal config: %v", err)
		}

		// 将YAML数据写入config.yaml
		if err := ioutil.WriteFile(configPath, configData, 0644); err != nil {
			log.Fatalf("Failed to write config file: %v", err)
		}

		fmt.Printf("Error：检测到你没有Config.yaml配置文件，已自动为您创建，修改后再次运行！\n")
	} else {
		// 读取现有的配置文件
		configData, err := ioutil.ReadFile(configPath)
		if err != nil {
			log.Fatalf("Failed to read config file: %v", err)
		}

		var config Config
		// 将YAML数据反序列化到Config结构体
		if err := yaml.Unmarshal(configData, &config); err != nil {
			log.Fatalf("Failed to unmarshal config: %v", err)
		}

		// 检查密钥是否设置
		if config.SecretKey == "" {
			fmt.Println("Error：你并没有设置启动密钥，请设置后再次运行！")
			os.Exit(1)
		}

		// 这里可以继续使用配置信息来启动服务
		fmt.Printf("监听端口： %d\n", config.Port)
	}

	// Load configuration from config.yaml
	var config Config
	configData, err := ioutil.ReadFile("config.yaml")
	if err != nil {
		log.Fatalf("Error reading config file: %v", err)
	}
	err = yaml.Unmarshal(configData, &config)
	if err != nil {
		log.Fatalf("Error parsing config file: %v", err)
	}

	// Validate the secret key
	expectedSecretKey := "自己找密钥" // Replace with your expected secret key
	if config.SecretKey != expectedSecretKey {
		log.Fatalf("Error：密钥错误！检查密钥后再试！")
	}

	// Set the server port from the configuration
	port := config.Port

	// 将端口号转换为字符串
	portStr := strconv.Itoa(port)

	http.HandleFunc("/send/message", webhookHandler)

	log.Printf("Server is running on :%s", portStr)
	err = http.ListenAndServe(":"+portStr, nil)
	if err != nil {
		log.Fatalf("Failed to start server: %v", err)
	}
}
